﻿/*
 * ========================================================================
 * Copyright(c) 2008-2010北京高阳金信信息技术有限公司, All Rights Reserved.
 * ========================================================================
 *  系统日志客户端，负责写日志文件，将日志消息发送到日志服务

 * 
 * 作者：邓太华     时间：2009-11-03
 * 版本：V1.0
 * 
 * 修改者：         时间：                
 * 修改说明：
 * ========================================================================
*/

using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Configuration;

namespace Hisuntech.SystemFramework.Log
{
    /// <summary>
    /// 日志级别
    /// </summary>
    public  enum LogLevel
    { 
        /// <summary>
        /// 正常日志，如调试
        /// </summary>
        Normal = 0,
        /// <summary>
        /// 低级别日志，如警告
        /// </summary>
        Low=1,
        /// <summary>
        /// 中级别日志，如一般性错误
        /// </summary>
        Mid=2,
        /// <summary>
        /// 高级别日志，如严重错误
        /// </summary>
        High=3
    }

    /// <summary>
    /// （写）日志的方式（已过时，有提供程序决定方式）
    /// </summary>
    public enum LogType
    { 
        /// <summary>
        /// 日志文件
        /// </summary>
        File,
        /// <summary>
        /// 数据库
        /// </summary>
        DataBase,
        /// <summary>
        /// Windows 系统事件日志
        /// </summary>
        WindowsEventsLog,
        /// <summary>
        /// 日志服务
        /// </summary>
        Service,
        /// <summary>
        /// 文见和日志服务
        /// </summary>
        FileAndService
        
    }
    
    /// <summary>
    /// 系统日志客户端，处理日志
    /// </summary>
    public abstract  class LogClient : ILogClient
    {
        #region private field
        private string _errMessage;
        private static string _appGuid;
        private static object lockObj = new object();

        //private LogType logType;
        //private static LogClient _instance;

        #endregion

        private static List<LogClient> _logProviderList ;
        /// <summary>
        /// 日志提供程序列表
        /// </summary>
        public  static List<LogClient> LogProviderList
        {
            get {
                if (_logProviderList == null)
                {
                    lock (lockObj)
                    {
                        if (_logProviderList == null)
                        {
                            _logProviderList = new List<LogClient>();

                            System.Collections.IDictionary LogProviderAssemblyDict = (System.Collections.IDictionary)ConfigurationManager.GetSection("LogProviderAssemblys");
                            if (LogProviderAssemblyDict != null)
                            {
                                foreach (string key in LogProviderAssemblyDict.Keys)
                                {
                                    string[] tempArr = LogProviderAssemblyDict[key].ToString ().Split(',');
                                    LogClient loger = (LogClient)Assembly.Load(tempArr[0]).CreateInstance(tempArr[1]);
                                    loger.ProviderKey = key;
                                    _logProviderList.Add(loger);
                                }
                            }
                        }
                    }
                }
                return _logProviderList;
            }
        }

        #region private function
        /// <summary>
        /// 获取入口程序的GUID字符串形式。注：Web站点和Web应用程序无法获取该值，请在应用程序配置文件里面做配置
        /// </summary>
        /// <returns></returns>
        private static string GetEntryAssemblyGuidString()
        {
            Assembly ass = Assembly.GetEntryAssembly();
            object[] attrs = ass.GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false);
            Guid id = new Guid(((System.Runtime.InteropServices.GuidAttribute)attrs[0]).Value);
            return id.ToString();
        }


        #endregion

        #region public property

        private string _providerKey;
        /// <summary>
        /// 日志提供程序标示，用于区别和读取提供程序的自定义属性
        /// </summary>
        public string ProviderKey
        {
            get { return _providerKey; }
            set { _providerKey = value; }
        }


        /// <summary>
        /// 写日志失败的错误信息
        /// </summary>
        public string ErrMessage
        {
            get { return _errMessage; }
            protected set { _errMessage = value; }
        }

        private static string _logWorkMessage;
        /// <summary>
        /// 日志操作信息
        /// </summary>
        public static string LogWorkMessage
        {
            get { return _logWorkMessage; }
            protected set { _logWorkMessage = value; }
        }
        

        /// <summary>
        /// 获取或设置应用程序的唯一标示，对于ASP.NET网站，没有该GUID，请手工设置或者在应用程序配置节中配置 AppGuid 键和值。
        /// </summary>
        public static string AppGuid
        {
            get
            {
                if (string.IsNullOrEmpty(_appGuid))
                {
                    if (!string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["AppGuid"]))
                        _appGuid = System.Configuration.ConfigurationManager.AppSettings["AppGuid"];
                    else
                        _appGuid = GetEntryAssemblyGuidString();
                }
                return _appGuid;
            }
            set { _appGuid = value; }
        }
        #endregion
               

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public LogClient()
        {
            //string  strlogType = System.Configuration.ConfigurationManager.AppSettings["LogType"];
            //if (!string.IsNullOrEmpty(strlogType))
            //    logType = (LogType)Enum.Parse(typeof(LogType), strlogType, true);
            //else
            //    logType = LogType.File;
            //
        }

        /// <summary>
        /// 日志提供程序自定义属性值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string LogProviderPropertyValue(string key)
        {
            System.Collections.IDictionary LogProviderProperty = (System.Collections.IDictionary )ConfigurationManager.GetSection("LogProviderProperty");
            if (LogProviderProperty != null)
            {
                key =this.ProviderKey+ ":"+key;
                if (LogProviderProperty.Contains (key))
                    return LogProviderProperty[key].ToString ();
            }
            //throw new Exception("应用程序配置文件配置节 LogProviderProperty 没有添加属性 " + key);
            return "";
        }

       


        #region public function
       
        /// <summary>
        /// 写日志的抽象方法
        /// </summary>
        /// <param name="logInfo">日志信息类</param>
        /// <returns></returns>
        public abstract bool WriteLog(LogInfo logInfo);

        /// <summary>
        /// 自动写日志
        /// </summary>
        /// <param name="log">日志信息类</param>
        /// <returns>是否成功</returns>
        public static bool AutoWriteLog(LogInfo log)
        {
            
            bool flag = true;
            foreach (LogClient client in LogProviderList)
            {
                if (!client.WriteLog(log))
                    flag = false;
            }
            return flag;
        }

        /// <summary>
        /// 自动写日志信息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool AutoWriteLog(string message)
        {
            LogInfo info = new LogInfo();
            info.Level = LogLevel.Normal;
            info.LogTime = DateTime.Now;
            info.Source = AppGuid;
            info.TypeName = "";
            info.Number = 0;
            info.Catalog = "";
            info.Message = message;
            return AutoWriteLog(info);
        }

       
        #endregion

    }
}
